package socketmvc.core.codec;

import org.tio.websocket.common.util.BASE64Util;
import socketmvc.core.util.BytesUtils;
import socketmvc.core.util.JsonKit;
import socketmvc.core.exception.DecodeBufferLen0Exception;
import socketmvc.core.packets.basic.IPacket;
import socketmvc.core.packets.basic.Protocol;
import socketmvc.core.packets.basic.impl.JsonBase64Packet;
import socketmvc.core.packets.basic.impl.JsonTextBody;

import java.nio.ByteBuffer;
import java.util.Optional;

public class JsonTextBase64ContentCodec extends AbstractCodec {

    protected final int HEADER_LENGTH = 9;

    @Override
    public JsonBase64Packet decode(ByteBuffer buffer) {

        int readableLength = getBufferReadableLength(buffer);
        // 数据包可读长度小于5，证明数据不够（5代表协议头部有5bytes,1byte协议版本号码，4byte报文内容的长度）
        if (readableLength < HEADER_LENGTH){
            return null;
        }
        byte version = buffer.get(); // 1byte版本号
        int textBodyLen = buffer.getInt(); //4byte 文本内容长度
        int binBodyLen = buffer.getInt(); // 4byte 二进制内容长度
        if (textBodyLen <= 0){
            // 抛出协议异常
            throw new DecodeBufferLen0Exception();
        }
        //计算本次需要的数据长度
        int neededLength = HEADER_LENGTH + textBodyLen + binBodyLen;
        //收到的数据是否足够组包
        int isDataEnough = readableLength - neededLength;

        if (isDataEnough >= 0) { //组包成功
            byte[] textBodyBytes = new byte[textBodyLen];
            buffer.get(textBodyBytes);
            byte[] binBodyBytes = new byte[binBodyLen];
            buffer.get(binBodyBytes);
            buffer.rewind();
            return new JsonBase64Packet(
                    JsonKit.toBean(BytesUtils.bytesToString(textBodyBytes), JsonTextBody.class),
                    BytesUtils.bytesToString(binBodyBytes));
        }

        return null;
    }

    @Override
    public ByteBuffer encode(IPacket packet) {
        byte version = packet.protocolVersion();
        byte[] textBodyBytes = BytesUtils.stringToBytes(packet.getTextBodyAsStr());
        byte[] binBodyAsBytes = Optional.ofNullable(packet.getBinBodyAsBytes()).orElse(new byte[0]);
        if (binBodyAsBytes.length > 0){
            // 将字节转换成base64
            String binBodyHex = BASE64Util.byteArrayToBase64(binBodyAsBytes);
            binBodyAsBytes = BytesUtils.stringToBytes(binBodyHex);
        }
        // 4byte 文本段正文长度
        int textBodyLength = textBodyBytes.length;
        // 4byte 二进制段正文长度
        int binBodyLength = binBodyAsBytes.length;

        int allLength = 1 + 4 + 4 + textBodyLength + binBodyLength;
        ByteBuffer buffer = ByteBuffer.allocate(allLength);
        buffer.put(version);  // 1byte协议版本号
        buffer.putInt(textBodyLength); // 4byte 文本段正文长度
        buffer.putInt(binBodyLength); // 4byte 二进制段正文长度
        buffer.put(textBodyBytes); // n byte 文本段正文
        buffer.put(binBodyAsBytes); // n byte 二进制段正文
        return buffer;
    }

    @Override
    public byte protocolVersion() {
        return Protocol.JSON_TEXT_BASE64_CONTENT.getVersion();
    }
}
